<?php
// +----------------------------------------------------------------------
// | all for fight
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.quntiao.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com>
// +----------------------------------------------------------------------

namespace Admin\Controller;

/**
 * 扩展后台管理页面
 * @author yangweijie <yangweijiester@gmail.com>
 */
class AddonsController extends AdminController {

	public function _initialize(){
		$this->assign('_extra_menu',array(
            '已装插件后台'=> D('Addons')->getAdminList(),
		));
		parent::_initialize();
	}

	//创建向导首页
	public function create(){
		if(!is_writable(ONETHINK_ADDON_PATH))
		$this->error('您没有创建目录写入权限，无法使用此功能');

		$hooks = M('Hooks')->field('name,description')->select();
		$this->assign('Hooks',$hooks);
		$this->meta_title = '创建向导';
		$this->display('create');
	}

	//预览
	public function preview($output = true){
		$data                   =   $_POST;
		$data['info']['status'] =   (int)$data['info']['status'];
		$extend                 =   array();
		$custom_config          =   trim($data['custom_config']);
		if($data['has_config'] && $custom_config){
			$custom_config = <<<str


        public \$custom_config = '{$custom_config}';
str;
			$extend[] = $custom_config;
		}

		$admin_list = trim($data['admin_list']);
		if($data['has_adminlist'] && $admin_list){
			$admin_list = <<<str


        public \$admin_list = array(
        {$admin_list}
        );
str;
        $extend[] = $admin_list;
		}

		$custom_adminlist = trim($data['custom_adminlist']);
		if($data['has_adminlist'] && $custom_adminlist){
			$custom_adminlist = <<<str


        public \$custom_adminlist = '{$custom_adminlist}';
str;
			$extend[] = $custom_adminlist;
		}

		$extend = implode('', $extend);
		$hook = '';
		foreach ($data['hook'] as $value) {
			$hook .= <<<str
        //实现的{$value}钩子方法
        public function {$value}(\$param){

        }

str;
		}

		$tpl = <<<str
<?php

namespace Addons\\{$data['info']['name']};
use Common\Controller\Addon;

/**
 * {$data['info']['title']}插件
 * @author {$data['info']['author']}
 */

    class {$data['info']['name']}Addon extends Addon{

        public \$info = array(
            'name'=>'{$data['info']['name']}',
            'title'=>'{$data['info']['title']}',
            'description'=>'{$data['info']['description']}',
            'status'=>{$data['info']['status']},
            'author'=>'{$data['info']['author']}',
            'version'=>'{$data['info']['version']}'
        );{$extend}

        public function install(){
            return true;
        }

        public function uninstall(){
            return true;
        }

        {$hook}
    }
str;
        if($output)
        exit($tpl);
        else
        return $tpl;
	}

	public function checkForm(){
		$data                   =   $_POST;
		$data['info']['name']   =   trim($data['info']['name']);
		if(!$data['info']['name'])
		$this->error('插件标识必须');
		//检测插件名是否合法
		$addons_dir             =   ONETHINK_ADDON_PATH;
		if(file_exists("{$addons_dir}{$data['info']['name']}")){
			$this->error('插件已经存在了');
		}
		$this->success('可以创建');
	}

	public function build(){
		$data                   =   $_POST;
		$data['info']['name']   =   trim($data['info']['name']);
		$addonFile              =   $this->preview(false);
		$addons_dir             =   ONETHINK_ADDON_PATH;
		//创建目录结构
		$files          =   array();
		$addon_dir      =   "$addons_dir{$data['info']['name']}/";
		$files[]        =   $addon_dir;
		$addon_name     =   "{$data['info']['name']}Addon.class.php";
		$files[]        =   "{$addon_dir}{$addon_name}";
		if($data['has_config'] == 1);//如果有配置文件
		$files[]    =   $addon_dir.'config.php';

		if($data['has_outurl']){
			$files[]    =   "{$addon_dir}Controller/";
			$files[]    =   "{$addon_dir}Controller/{$data['info']['name']}Controller.class.php";
			$files[]    =   "{$addon_dir}Model/";
			$files[]    =   "{$addon_dir}Model/{$data['info']['name']}Model.class.php";
		}
		$custom_config  =   trim($data['custom_config']);
		if($custom_config)
		$data[]     =   "{$addon_dir}{$custom_config}";

		$custom_adminlist = trim($data['custom_adminlist']);
		if($custom_adminlist)
		$data[]     =   "{$addon_dir}{$custom_adminlist}";

		create_dir_or_files($files);

		//写文件
		file_put_contents("{$addon_dir}{$addon_name}", $addonFile);
		if($data['has_outurl']){
			$addonController = <<<str
<?php

namespace Addons\\{$data['info']['name']}\Controller;
use Home\Controller\AddonsController;

class {$data['info']['name']}Controller extends AddonsController{

}

str;
			file_put_contents("{$addon_dir}Controller/{$data['info']['name']}Controller.class.php", $addonController);
			$addonModel = <<<str
<?php

namespace Addons\\{$data['info']['name']}\Model;
use Think\Model;

/**
 * {$data['info']['name']}模型
 */
class {$data['info']['name']}Model extends Model{

}

str;
			file_put_contents("{$addon_dir}Model/{$data['info']['name']}Model.class.php", $addonModel);
		}

		if($data['has_config'] == 1)
		file_put_contents("{$addon_dir}config.php", $data['config']);

		$this->success('创建成功',U('index'));
	}

	/**
	 * 插件列表
	 */
	public function index(){
		$this->meta_title = '插件列表';
		$list       =   D('Addons')->getList();
		$request    =   (array)I('request.');
		$total      =   $list? count($list) : 1 ;
		$listRows   =   C('LIST_ROWS') > 0 ? C('LIST_ROWS') : 10;
		$page       =   new \Think\Page($total, $listRows, $request);
		$voList     =   array_slice($list, $page->firstRow, $page->listRows);
		$p          =   $page->show();
		$this->assign('_list', $voList);
		$this->assign('_page', $p? $p: '');
		// 记录当前列表页的cookie
		Cookie('__forward__',$_SERVER['REQUEST_URI']);
		$this->display();
	}

	/**
	 * 插件后台显示页面
	 * @param string $name 插件名
	 */
	public function adminList($name){
		// 记录当前列表页的cookie
		Cookie('__forward__',$_SERVER['REQUEST_URI']);
		$class = get_addon_class($name);
		if(!class_exists($class))
		$this->error('插件不存在');
		$addon  =   new $class();
		$this->assign('addon', $addon);
		$param  =   $addon->admin_list;
		if(!$param)
		$this->error('插件列表信息不正确');
		$this->meta_title = $addon->info['title'];
		extract($param);
		$this->assign('title', $addon->info['title']);
		$this->assign($param);
		if(!isset($fields))
		$fields = '*';
		if(!isset($map))
		$map = array();
		if(isset($model))
		$list = $this->lists(D("Addons://{$model}/{$model}")->field($fields),$map);
		$this->assign('_list', $list);
		if($addon->custom_adminlist)
		$this->assign('custom_adminlist', $this->fetch($addon->addon_path.$addon->custom_adminlist));
		$this->display();
	}

	/**
	 * 启用插件
	 */
	public function enable(){
		$id     =   I('id');
		$msg    =   array('success'=>'启用成功', 'error'=>'启用失败');
		S('hooks', null);
		$this->resume('Addons', "id={$id}", $msg);
	}

	/**
	 * 禁用插件
	 */
	public function disable(){
		$id     =   I('id');
		$msg    =   array('success'=>'禁用成功', 'error'=>'禁用失败');
		S('hooks', null);
		$this->forbid('Addons', "id={$id}", $msg);
	}

	/**
	 * 设置插件页面
	 */
	public function config(){
		$id     =   (int)I('id');
		$addon  =   M('Addons')->find($id);
		if(!$addon)
		$this->error('插件未安装');
		$addon_class = get_addon_class($addon['name']);
		if(!class_exists($addon_class))
		trace("插件{$addon['name']}无法实例化,",'ADDONS','ERR');
		$data  =   new $addon_class;
		$addon['addon_path'] = $data->addon_path;
		$addon['custom_config'] = $data->custom_config;
		$this->meta_title   =   '设置插件-'.$data->info['title'];
		$db_config = $addon['config'];
		$addon['config'] = include $data->config_file;
		if($db_config){
			$db_config = json_decode($db_config, true);
			foreach ($addon['config'] as $key => $value) {
				if($value['type'] != 'group'){
					$addon['config'][$key]['value'] = $db_config[$key];
				}else{
					foreach ($value['options'] as $gourp => $options) {
						foreach ($options['options'] as $gkey => $value) {
							$addon['config'][$key]['options'][$gourp]['options'][$gkey]['value'] = $db_config[$gkey];
						}
					}
				}
			}
		}
		$this->assign('data',$addon);
		if($addon['custom_config'])
		$this->assign('custom_config', $this->fetch($addon['addon_path'].$addon['custom_config']));
		$this->display();
	}

	/**
	 * 保存插件设置
	 */
	public function saveConfig(){
		$id     =   (int)I('id');
		$config =   I('config');
		$flag = M('Addons')->where("id={$id}")->setField('config',json_encode($config));
		if($flag !== false){
			$this->success('保存成功', Cookie('__forward__'));
		}else{
			$this->error('保存失败');
		}
	}

	/**
	 * 安装插件
	 */
	public function install(){
		$addon_name     =   trim(I('addon_name'));
		$class          =   get_addon_class($addon_name);
		if(!class_exists($class))
		$this->error('插件不存在');
		$addons  =   new $class;
		$info = $addons->info;
		if(!$info || !$addons->checkInfo())//检测信息的正确性
		$this->error('插件信息缺失');
		session('addons_install_error',null);
		$install_flag   =   $addons->install();
		if(!$install_flag){
			$this->error('执行插件预安装操作失败'.session('addons_install_error'));
		}
		$addonsModel    =   D('Addons');
		$data           =   $addonsModel->create($info);
		if(is_array($addons->admin_list) && $addons->admin_list !== array()){
			$data['has_adminlist'] = 1;
		}else{
			$data['has_adminlist'] = 0;
		}
		if(!$data)
		$this->error($addonsModel->getError());
		if($addonsModel->add($data)){
			$config         =   array('config'=>json_encode($addons->getConfig()));
			$addonsModel->where("name='{$addon_name}'")->save($config);
			$hooks_update   =   D('Hooks')->updateHooks($addon_name);
			if($hooks_update){
				S('hooks', null);
				$this->success('安装成功');
			}else{
				$addonsModel->where("name='{$addon_name}'")->delete();
				$this->error('更新钩子处插件失败,请卸载后尝试重新安装');
			}

		}else{
			$this->error('写入插件数据失败');
		}
	}

	/**
	 * 卸载插件
	 */
	public function uninstall(){
		$addonsModel    =   M('Addons');
		$id             =   trim(I('id'));
		$db_addons      =   $addonsModel->find($id);
		$class          =   get_addon_class($db_addons['name']);
		$this->assign('jumpUrl',U('index'));
		if(!$db_addons || !class_exists($class))
		$this->error('插件不存在');
		session('addons_uninstall_error',null);
		$addons =   new $class;
		$uninstall_flag =   $addons->uninstall();
		if(!$uninstall_flag)
		$this->error('执行插件预卸载操作失败'.session('addons_uninstall_error'));
		$hooks_update   =   D('Hooks')->removeHooks($db_addons['name']);
		if($hooks_update === false){
			$this->error('卸载插件所挂载的钩子数据失败');
		}
		S('hooks', null);
		$delete = $addonsModel->where("name='{$db_addons['name']}'")->delete();
		if($delete === false){
			$this->error('卸载插件失败');
		}else{
			$this->success('卸载成功');
		}
	}

	/**
	 * 钩子列表
	 */
	public function hooks(){
		$this->meta_title   =   '钩子列表';
		$map    =   $fields =   array();
		$list   =   $this->lists(D("Hooks")->field($fields),$map);
		int_to_string($list, array('type'=>C('HOOKS_TYPE')));
		// 记录当前列表页的cookie
		Cookie('__forward__',$_SERVER['REQUEST_URI']);
		$this->assign('list', $list );
		$this->display();
	}

	public function addhook(){
		$this->assign('data', null);
		$this->meta_title = '新增钩子';
		$this->display('edithook');
	}

	//钩子出编辑挂载插件页面
	public function edithook($id){
		$hook = M('Hooks')->field(true)->find($id);
		$this->assign('data',$hook);
		$this->meta_title = '编辑钩子';
		$this->display('edithook');
	}

	//超级管理员删除钩子
	public function delhook($id){
		if(M('Hooks')->delete($id) !== false){
			$this->success('删除成功');
		}else{
			$this->error('删除失败');
		}
	}

	public function updateHook(){
		$hookModel  =   D('Hooks');
		$data       =   $hookModel->create();
		if($data){
			if($data['id']){
				$flag = $hookModel->save($data);
				if($flag !== false)
				$this->success('更新成功', Cookie('__forward__'));
				else
				$this->error('更新失败');
			}else{
				$flag = $hookModel->add($data);
				if($flag)
				$this->success('新增成功', Cookie('__forward__'));
				else
				$this->error('新增失败');
			}
		}else{
			$this->error($hookModel->getError());
		}
	}

	public function execute($_addons = null, $_controller = null, $_action = null){
		if(C('URL_CASE_INSENSITIVE')){
			$_addons        =   ucfirst(parse_name($_addons, 1));
			$_controller    =   parse_name($_controller,1);
		}

		if(!empty($_addons) && !empty($_controller) && !empty($_action)){
			$Addons = A("Addons://{$_addons}/{$_controller}")->$_action();
		} else {
			$this->error('没有指定插件名称，控制器或操作！');
		}
	}

}
